
        <html>
			<head>
			     <title>OpenSSL-CVE-2015-1793漏洞分析 - 360安全卫士</title>
				 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
			</head>
			<body>
				<h1>原文地址:<a href="http://drops.wooyun.org/papers/7073">http://drops.wooyun.org/papers/7073</a></h1>
				
      <p>
        <h1>0x00 前言</h1>

<hr />

<p>OpenSSL官方在7月9日发布了编号为 CVE-2015-1793 的交叉证书验证绕过漏洞，其中主要影响了OpenSSL的1.0.1和1.0.2分支。1.0.0和0.9.8分支不受影响。</p>

<p>360安全研究员au2o3t对该漏洞进行了原理上的分析，确认是一个绕过交叉链类型证书验证的高危漏洞，可以让攻击者构造证书来绕过交叉验证，用来形成诸如“中间人”等形式的攻击。</p>

<h1>0x01 漏洞基本原理</h1>

<hr />

<p>直接看最简单的利用方法（利用方法包括但不限于此）：</p>

<p>攻击者从一公共可信的 CA （C）处签得一证书 X，并以此证书签发另一证书 V（含对X的交叉引用），那么攻击者发出的证书链 V, R （R为任意证书）对信任 C 的用户将是可信的。</p>

<p>显然用户对 V, R 链的验证会返回失败。</p>

<!--more-->

<p>对不支持交叉链认证的老版本来说，验证过程将以失败结束。</p>

<p>对支持交叉认证的版本，则将会尝试构建交叉链 <code>V, X, C</code>，并继续进行验证。</p>

<p>虽然 <code>V, X, C</code> 链能通过可信认证，但会因 X 的用法不包括 CA 而导致验证失败。</p>

<p>但在 openssl-1.0.2c 版本，因在对交叉链的处理中，对最后一个不可信证书位置计数的错误，导致本应对 V, X 记为不可信并验证，错记为了仅对 V 做验证，而没有验证攻击者的证书 X，返回验证成功。</p>

<h1>0x02 具体漏洞分析</h1>

<hr />

<p>漏洞代码位于文件：<code>openssl-1.0.2c/crypto/x509/x509_vfy.c</code></p>

<p>函数：<code>X509_verify_cert()</code> 中</p>

<p>第 392 行：<code>ctx-&gt;last_untrusted–;</code></p>

<p>对问题函数 <code>X509_verify_cert</code> 的简单分析：</p>

<p>（ 为方便阅读，仅保留与证书验证强相关的代码，去掉了诸如变量定义、错误处理、资源释放等非主要代码）</p>

<p>问题在于由 <code>&lt;1&gt;</code> 处加入颁发者时及 <code>&lt;2&gt;</code> 处验证（颁发者）后，证书链计数增加，但 最后一个不可信证书位置计数 并未增加， 而在 <code>&lt;4&gt;</code> 处去除过程中 最后一个不可信证书位置计数 额外减少了，导致后面验证过程中少验。</p>

<p>（上述 <code>V, X, C</code> 链中应验 <code>V, X</code> 但少验了 <code>X</code>）</p>

<p>代码分析如下</p>

<pre><code>#!c++
int X509_verify_cert(X509_STORE_CTX *ctx)
{
    // 将 ctx-&gt;cert 做为不信任证书压入需验证链  ctx-&gt;chain
    // STACK_OF(X509) *chain 将被构造为证书链，并最终送到 internal_verify() 中去验证
    sk_X509_push(ctx-&gt;chain,ctx-&gt;cert); 
    // 当前链长度（==1）
    num = sk_X509_num(ctx-&gt;chain);
     // 取出第 num 个证书
    x = sk_X509_value(ctx-&gt;chain, num - 1);
     // 存在不信任链则复制之
    if (ctx-&gt;untrusted != NULL
        &amp;&amp; (sktmp = sk_X509_dup(ctx-&gt;untrusted)) == NULL) {
        X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
         goto end;
    }
     // 预设定的最大链深度（100）
    depth = param-&gt;depth;
    // 构造需验证证书链
    for (;;) {
        // 超长退出
        if (depth &lt; num)
            break;
        // 遇自签退出（链顶）
        if (cert_self_signed(x))
            break;
         if (ctx-&gt;untrusted != NULL) {
            xtmp = find_issuer(ctx, sktmp, x);
            // 当前证书为不信任颁发者（应需CA标志）颁发
            if (xtmp != NULL) {
                // 则加入需验证链
                if (!sk_X509_push(ctx-&gt;chain, xtmp)) {
                    X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
                    goto end;
                }
                CRYPTO_add(&amp;xtmp-&gt;references, 1, CRYPTO_LOCK_X509);
                (void)sk_X509_delete_ptr(sktmp, xtmp);
                // 最后一个不可信证书位置计数 自增1
                ctx-&gt;last_untrusted++;
                x = xtmp;
                num++;
                continue;
            }
        }
        break;
    }
    do {
        i = sk_X509_num(ctx-&gt;chain);
        x = sk_X509_value(ctx-&gt;chain, i - 1);
        // 若最顶证书是自签的
        if (cert_self_signed(x)) {
            // 若需验证链长度 == 1
            if (sk_X509_num(ctx-&gt;chain) == 1) {
                // 在可信链中查找其颁发者（找自己）
                ok = ctx-&gt;get_issuer(&amp;xtmp, ctx, x);

               // 没找到或不是相同证书
                if ((ok &lt;= 0) || X509_cmp(x, xtmp)) {
                    ctx-&gt;error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
                    ctx-&gt;current_cert = x;
                    ctx-&gt;error_depth = i - 1;
                    if (ok == 1)
                        X509_free(xtmp);
                    bad_chain = 1;
                    ok = cb(0, ctx);
                    if (!ok)
                        goto end;
                // 找到
                } else {
                    X509_free(x);
                    x = xtmp;
                    // 入到可信链
                    (void)sk_X509_set(ctx-&gt;chain, i - 1, x);
                    // 最后一个不可信证书位置计数 置0
                    ctx-&gt;last_untrusted = 0;
                }
            // 最顶为自签证书 且 证书链长度&gt;1
            } else {
                // 弹出
                chain_ss = sk_X509_pop(ctx-&gt;chain);
                // 最后一个不可信证书位置计数 自减
                ctx-&gt;last_untrusted--;
                num--;
                j--;
                // 保持指向当前最顶证书
                x = sk_X509_value(ctx-&gt;chain, num - 1);
            }
        }
        // &lt;1&gt;
        // 继续构造证书链（加入颁发者）
        for (;;) {
            // 自签退出
            if (cert_self_signed(x))
                break;
            // 在可信链中查找其颁发者
            ok = ctx-&gt;get_issuer(&amp;xtmp, ctx, x);
            // 出错
            if (ok &lt; 0)
                return ok;
            // 没找到
            if (ok == 0)
                 break;
            x = xtmp;
            // 将不可信证书的颁发者（证书）加入需验证证书链
            if (!sk_X509_push(ctx-&gt;chain, x)) {
                X509_free(xtmp);
                X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
                return 0;
            }
            num++;
        }
        // &lt;2&gt;
        // 验证 for(;;) 中加入的颁发者链
        i = check_trust(ctx);
        if (i == X509_TRUST_REJECTED)
            goto end;
        retry = 0;
         // &lt;3&gt;
        // 检查交叉链
        if (i != X509_TRUST_TRUSTED
            &amp;&amp; !(ctx-&gt;param-&gt;flags &amp; X509_V_FLAG_TRUSTED_FIRST)
            &amp;&amp; !(ctx-&gt;param-&gt;flags &amp; X509_V_FLAG_NO_ALT_CHAINS)) {
            while (j-- &gt; 1) {
                xtmp2 = sk_X509_value(ctx-&gt;chain, j - 1);
                 // 其实得到一个“看似合理”的证书就返回，这里实际上仅仅根据 CN域 查找颁发者
                ok = ctx-&gt;get_issuer(&amp;xtmp, ctx, xtmp2);
                if (ok &lt; 0)
                    goto end;
                // 存在交叉链
                if (ok &gt; 0) {
                    X509_free(xtmp);

                    // 去除交叉链以上部分
                    while (num &gt; j) {
                        xtmp = sk_X509_pop(ctx-&gt;chain);
                        X509_free(xtmp);
                        num--;
                        // &lt;4&gt;
                        // 问题所在
                        ctx-&gt;last_untrusted--;
                    }
                    // &lt;5&gt;
                    retry = 1;
                    break;
                }
            }
        }
    } while (retry);
    ……
}
</code></pre>

<p>官方的解决方法是在 <code>&lt;5&gt;</code> 处重新计算 最后一个不可信证书位置计数 的值为链长：</p>

<pre><code>ctx-&gt;last_untrusted = sk_X509_num(ctx-&gt;chain);
</code></pre>

<p>并去掉 <code>&lt;4&gt;</code> 处的 最后一个不可信证书位置计数 自减运算（其实去不去掉都无所谓）。 另一个解决办法可以是在 <code>&lt;1&gt; &lt;2&gt;</code> 后，在 <code>&lt;3&gt;</code> 处重置 最后一个不可信证书位置计数，加一行：</p>

<pre><code>ctx-&gt;last_untrusted = num;
</code></pre>

<p>这样 <code>&lt;4&gt;</code> 处不用删除，而逻辑也是合理并前后一致的。</p>

<h1>0x03 漏洞验证</h1>

<hr />

<p>笔者修改了部分代码并做了个Poc 。 修改代码：</p>

<pre><code>#!c++
int X509_verify_cert(X509_STORE_CTX *ctx)
{
    X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
    int bad_chain = 0;
    X509_VERIFY_PARAM *param = ctx-&gt;param;
    int depth, i, ok = 0;
    int num, j, retry;
    int (*cb) (int xok, X509_STORE_CTX *xctx);
    STACK_OF(X509) *sktmp = NULL;
    if (ctx-&gt;cert == NULL) {
        X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
        return -1;
    }

    cb = ctx-&gt;verify_cb;

    /*
     * first we make sure the chain we are going to build is present and that
     * the first entry is in place
     */
    if (ctx-&gt;chain == NULL) {
        if (((ctx-&gt;chain = sk_X509_new_null()) == NULL) ||
            (!sk_X509_push(ctx-&gt;chain, ctx-&gt;cert))) {
            X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
            goto end;
        }
        CRYPTO_add(&amp;ctx-&gt;cert-&gt;references, 1, CRYPTO_LOCK_X509);
        ctx-&gt;last_untrusted = 1;
    }

    /* We use a temporary STACK so we can chop and hack at it */
    if (ctx-&gt;untrusted != NULL
        &amp;&amp; (sktmp = sk_X509_dup(ctx-&gt;untrusted)) == NULL) {
        X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
        goto end;
    }

    num = sk_X509_num(ctx-&gt;chain);
    x = sk_X509_value(ctx-&gt;chain, num - 1);
    depth = param-&gt;depth;

    for (;;) {
        /* If we have enough, we break */
        if (depth &lt; num)
            break;              /* FIXME: If this happens, we should take
                                 * note of it and, if appropriate, use the
                                 * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
                                 * later. */

        /* If we are self signed, we break */
        if (cert_self_signed(x))
            break;

        /*
         * If asked see if we can find issuer in trusted store first
         */
        if (ctx-&gt;param-&gt;flags &amp; X509_V_FLAG_TRUSTED_FIRST) {
            ok = ctx-&gt;get_issuer(&amp;xtmp, ctx, x);
            if (ok &lt; 0)
                return ok;
            /*
             * If successful for now free up cert so it will be picked up
             * again later.
             */
            if (ok &gt; 0) {
                X509_free(xtmp);
                break;
            }
        }

        /* If we were passed a cert chain, use it first */
        if (ctx-&gt;untrusted != NULL) {
            xtmp = find_issuer(ctx, sktmp, x);
            if (xtmp != NULL) {
                if (!sk_X509_push(ctx-&gt;chain, xtmp)) {
                    X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
                    goto end;
                }
                CRYPTO_add(&amp;xtmp-&gt;references, 1, CRYPTO_LOCK_X509);
                (void)sk_X509_delete_ptr(sktmp, xtmp);
                ctx-&gt;last_untrusted++;
                x = xtmp;
                num++;
                /*
                 * reparse the full chain for the next one
                 */
                continue;
            }
        }
        break;
    }

    /* Remember how many untrusted certs we have */
    j = num;
    /*
     * at this point, chain should contain a list of untrusted certificates.
     * We now need to add at least one trusted one, if possible, otherwise we
     * complain.
     */

    do {
        /*
         * Examine last certificate in chain and see if it is self signed.
         */
        i = sk_X509_num(ctx-&gt;chain);
        x = sk_X509_value(ctx-&gt;chain, i - 1);
        if (cert_self_signed(x)) {
            /* we have a self signed certificate */
            if (sk_X509_num(ctx-&gt;chain) == 1) {
                /*
                 * We have a single self signed certificate: see if we can
                 * find it in the store. We must have an exact match to avoid
                 * possible impersonation.
                 */
                ok = ctx-&gt;get_issuer(&amp;xtmp, ctx, x);
                if ((ok &lt;= 0) || X509_cmp(x, xtmp)) {
                    ctx-&gt;error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
                    ctx-&gt;current_cert = x;
                    ctx-&gt;error_depth = i - 1;
                    if (ok == 1)
                        X509_free(xtmp);
                    bad_chain = 1;
                    ok = cb(0, ctx);
                    if (!ok)
                        goto end;
                } else {
                    /*
                     * We have a match: replace certificate with store
                     * version so we get any trust settings.
                     */
                    X509_free(x);
                    x = xtmp;
                    (void)sk_X509_set(ctx-&gt;chain, i - 1, x);
                    ctx-&gt;last_untrusted = 0;
                }
            } else {
                /*
                 * extract and save self signed certificate for later use
                 */
                chain_ss = sk_X509_pop(ctx-&gt;chain);
                ctx-&gt;last_untrusted--;
                num--;
                j--;
                x = sk_X509_value(ctx-&gt;chain, num - 1);
            }
        }
        /* We now lookup certs from the certificate store */
        for (;;) {
            /* If we have enough, we break */
            if (depth &lt; num)
                break;
            /* If we are self signed, we break */
            if (cert_self_signed(x))
                break;
            ok = ctx-&gt;get_issuer(&amp;xtmp, ctx, x);

            if (ok &lt; 0)
                return ok;
            if (ok == 0)
                break;
            x = xtmp;
            if (!sk_X509_push(ctx-&gt;chain, x)) {
                X509_free(xtmp);
                X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
                return 0;
            }
            num++;
        }

        /* we now have our chain, lets check it... */
        i = check_trust(ctx);

        /* If explicitly rejected error */
        if (i == X509_TRUST_REJECTED)
            goto end;

        /*
         * If it's not explicitly trusted then check if there is an alternative
         * chain that could be used. We only do this if we haven't already
         * checked via TRUSTED_FIRST and the user hasn't switched off alternate
         * chain checking
         */
        retry = 0;
// &lt;1&gt;
//ctx-&gt;last_untrusted = num;            


        if (i != X509_TRUST_TRUSTED
            &amp;&amp; !(ctx-&gt;param-&gt;flags &amp; X509_V_FLAG_TRUSTED_FIRST)
            &amp;&amp; !(ctx-&gt;param-&gt;flags &amp; X509_V_FLAG_NO_ALT_CHAINS)) {
            while (j-- &gt; 1) {
                xtmp2 = sk_X509_value(ctx-&gt;chain, j - 1);
                ok = ctx-&gt;get_issuer(&amp;xtmp, ctx, xtmp2);
                if (ok &lt; 0)
                    goto end;
                /* Check if we found an alternate chain */
                if (ok &gt; 0) {
                    /*
                     * Free up the found cert we'll add it again later
                     */
                    X509_free(xtmp);

                    /*
                     * Dump all the certs above this point - we've found an
                     * alternate chain
                     */
                    while (num &gt; j) {
                        xtmp = sk_X509_pop(ctx-&gt;chain);
                        X509_free(xtmp);
                        num--;
                        ctx-&gt;last_untrusted--;
                    }
                    retry = 1;
                    break;
                }
            }
        }
    } while (retry);

printf(" num=%d, real-num=%d\n", ctx-&gt;last_untrusted, sk_X509_num(ctx-&gt;chain) );
    /*
     * If not explicitly trusted then indicate error unless it's a single
     * self signed certificate in which case we've indicated an error already
     * and set bad_chain == 1
     */


    if (i != X509_TRUST_TRUSTED &amp;&amp; !bad_chain) {
        if ((chain_ss == NULL) || !ctx-&gt;check_issued(ctx, x, chain_ss)) {
            if (ctx-&gt;last_untrusted &gt;= num)
                ctx-&gt;error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
            else
                ctx-&gt;error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
            ctx-&gt;current_cert = x;
        } else {
            sk_X509_push(ctx-&gt;chain, chain_ss);
            num++;
            ctx-&gt;last_untrusted = num;
            ctx-&gt;current_cert = chain_ss;
            ctx-&gt;error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
            chain_ss = NULL;
        }

        ctx-&gt;error_depth = num - 1;
        bad_chain = 1;
        ok = cb(0, ctx);
        if (!ok)
            goto end;
    }
printf("flag=1\n");
    /* We have the chain complete: now we need to check its purpose */
    ok = check_chain_extensions(ctx);

    if (!ok)
        goto end;

printf("flag=2\n");
    /* Check name constraints */

    ok = check_name_constraints(ctx);

    if (!ok)
        goto end;
printf("flag=3\n");
    ok = check_id(ctx);

    if (!ok)
        goto end;
printf("flag=4\n");
    /* We may as well copy down any DSA parameters that are required */
    X509_get_pubkey_parameters(NULL, ctx-&gt;chain);

    /*
     * Check revocation status: we do this after copying parameters because
     * they may be needed for CRL signature verification.
     */

    ok = ctx-&gt;check_revocation(ctx);
    if (!ok)
        goto end;
printf("flag=5\n");
    i = X509_chain_check_suiteb(&amp;ctx-&gt;error_depth, NULL, ctx-&gt;chain,
                                ctx-&gt;param-&gt;flags);
    if (i != X509_V_OK) {
        ctx-&gt;error = i;
        ctx-&gt;current_cert = sk_X509_value(ctx-&gt;chain, ctx-&gt;error_depth);
        ok = cb(0, ctx);
        if (!ok)
            goto end;
    }
printf("flag=6\n");
    /* At this point, we have a chain and need to verify it */
    if (ctx-&gt;verify != NULL)
        ok = ctx-&gt;verify(ctx);
    else
        ok = internal_verify(ctx);
    if (!ok)
        goto end;
printf("flag=7\n");
#ifndef OPENSSL_NO_RFC3779
    /* RFC 3779 path validation, now that CRL check has been done */
    ok = v3_asid_validate_path(ctx);
    if (!ok)
        goto end;
    ok = v3_addr_validate_path(ctx);
    if (!ok)
        goto end;
#endif

printf("flag=8\n");
    /* If we get this far evaluate policies */
    if (!bad_chain &amp;&amp; (ctx-&gt;param-&gt;flags &amp; X509_V_FLAG_POLICY_CHECK))
        ok = ctx-&gt;check_policy(ctx);
    if (!ok)
        goto end;
    if (0) {
 end:
        X509_get_pubkey_parameters(NULL, ctx-&gt;chain);
    }
    if (sktmp != NULL)
        sk_X509_free(sktmp);
    if (chain_ss != NULL)
        X509_free(chain_ss);
printf("ok=%d\n", ok );        
    return ok;
}

Poc:
?
//
//里头的证书文件自己去找一个，这个不提供了
//
#include &lt;stdio.h&gt;
#include &lt;openssl/crypto.h&gt;
#include &lt;openssl/bio.h&gt;
#include &lt;openssl/x509.h&gt;
#include &lt;openssl/pem.h&gt;


STACK_OF(X509) *load_certs_from_file(const char *file)
{
    STACK_OF(X509) *certs;
    BIO *bio;
    X509 *x;
    bio = BIO_new_file( file, "r");
    certs = sk_X509_new_null();
    do
    {
        x = PEM_read_bio_X509(bio, NULL, 0, NULL);
        sk_X509_push(certs, x);
    }while( x != NULL );

    return certs;
}


void test(void)
{
    X509 *x = NULL;
    STACK_OF(X509) *untrusted = NULL;
    BIO *bio = NULL;
    X509_STORE_CTX *sctx = NULL;
    X509_STORE *store = NULL;
    X509_LOOKUP *lookup = NULL;

    store = X509_STORE_new();
    lookup = X509_STORE_add_lookup( store, X509_LOOKUP_file() );
    X509_LOOKUP_load_file(lookup, "roots.pem", X509_FILETYPE_PEM);
    untrusted = load_certs_from_file("untrusted.pem");
    bio = BIO_new_file("bad.pem", "r");
    x = PEM_read_bio_X509(bio, NULL, 0, NULL);
    sctx = X509_STORE_CTX_new();
    X509_STORE_CTX_init(sctx, store, x, untrusted);
    X509_verify_cert(sctx);
}

int main(void)
{
    test();
    return 0;
}
</code></pre>

<p>将代码中 <code>X509_verify_cert()</code> 函数加入输出信息如下： 编译，以伪造证书测试，程序输出信息为：</p>

<pre><code>num=1, real-num=3
flag=1
flag=2
flag=3
flag=4
flag=5
flag=6
flag=7
flag=8
ok=1
</code></pre>

<p>认证成功 将 <code>&lt;1&gt;</code> 处注释代码去掉，编译，再以伪造证书测试，程序输出信息为：</p>

<pre><code>num=3, real-num=3
flag=1
ok=0
</code></pre>

<p>认证失败</p>

<h1>0x04 安全建议</h1>

<hr />

<p>建议使用受影响版本（<code>OpenSSL 1.0.2b/1.0.2c</code> 和 <code>OpenSSL 1.0.1n/1.0.1o</code>）的 产品或代码升级OpenSSL到最新版本</p>      </p>
    
			</body>
		</html>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          